﻿namespace MyThread
{
    /// <summary>
    /// 异步线程帮助类
    /// </summary>
    public class MyThreadHelper
    {

        /// <summary>
        /// 开始后台线程
        /// </summary>
        /// <param name="action"></param>
        public static void StartBackgroundThread(Action action)
        {
            try
            {
                Thread thread = new Thread(new ThreadStart(action))
                {
                    IsBackground = true
                };
                thread.Start();
            }
            catch { }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="milliseconds"></param>
        /// <returns></returns>
        public static Task? Delay(int milliseconds)
        {
            try
            {
                var tcs = new TaskCompletionSource<object>();
                var timer = new System.Timers.Timer(milliseconds) { AutoReset = false };
                timer.Elapsed += delegate { timer.Dispose(); tcs.SetResult(new object()); };
                timer.Start();
                return tcs.Task;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 异步执行方法-无参数无返回值调用
        /// </summary>
        /// <param name="action">方法名</param>
        /// <param name="delay">延迟时间（秒）</param>
        public static async void RunDelayAsync(Action action, int delay)
        {
            try
            {
                await Task.Run(async () =>
                {
                    action();
                    await Task.Delay(delay * 1000);
                });
            }
            catch { }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="action"></param>
        /// <param name="t"></param>
        /// <param name="delay">延迟时间（秒）</param>
        public static async void RunDelayAsync<T>(Action<T> action, T t, int delay)
        {
            try
            {
                await Task.Run(async () =>
                {
                    action(t);
                    await Task.Delay(delay * 1000);
                });
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-无参数无返回值调用
        /// </summary>
        /// <param name="action">方法名</param>
        public static async void RunAsync(Action action)
        {
            try
            {
                await Task.Run(() =>
                {
                    action();
                });
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-带参数无返回值的调用
        /// </summary>
        /// <typeparam name="T">参数对象泛型</typeparam>
        /// <param name="action">方法名</param>
        /// <param name="t">参数</param>
        public static async void RunAsync<T>(Action<T> action, T t)
        {
            try
            {
                await Task.Run(() =>
                {
                    action(t);
                });
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-带参数无返回值的调用
        /// </summary>
        /// <typeparam name="T1">参数对象泛型</typeparam>
        /// <typeparam name="T2">参数对象泛型</typeparam>
        /// <param name="action">方法名</param>
        /// <param name="t1">参数</param>
        /// <param name="t2">参数</param>
        public static async void RunAsync<T1, T2>(Action<T1, T2> action, T1 t1, T2 t2)
        {
            try
            {
                await Task.Run(() =>
                {
                    action(t1, t2);
                });
            }
            catch { }
        }

        /// <summary>
        /// 带参数无返回值的调用
        /// </summary>
        /// <typeparam name="T1">参数对象泛型</typeparam>
        /// <typeparam name="T2">参数对象泛型</typeparam>
        /// <typeparam name="T3">参数对象泛型</typeparam>
        /// <param name="action">方法名</param>
        /// <param name="t1">参数</param>
        /// <param name="t2">参数</param>
        /// <param name="t3">参数</param>
        public static async void RunAsync<T1, T2, T3>(Action<T1, T2, T3> action, T1 t1, T2 t2, T3 t3)
        {
            try
            {
                await Task.Run(() =>
                {
                    action(t1, t2, t3);
                });
            }
            catch { }
        }

        /// <summary>
        /// 带参数无返回值的调用
        /// </summary>
        /// <typeparam name="T1">参数对象泛型</typeparam>
        /// <typeparam name="T2">参数对象泛型</typeparam>
        /// <typeparam name="T3">参数对象泛型</typeparam>
        /// <param name="action">方法名</param>
        /// <param name="t1">参数</param>
        /// <param name="t2">参数</param>
        /// <param name="t3">参数</param>
        public static async void RunAsync<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 t1, T2 t2, T3 t3, T4 t4)
        {
            try
            {
                await Task.Run(() =>
                {
                    action(t1, t2, t3, t4);
                });
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-无参数有返回值调用
        /// </summary>
        /// <typeparam name="TResult">返回值对象泛型</typeparam>
        /// <param name="func">方法名</param>
        /// <returns>返回Task对象</returns>
        public static async Task<TResult?> RunAsync<TResult>(Func<TResult> func)
        {
            try
            {
                await Task.Run(() =>
                {
                    return func();
                });
            }
            catch { }
            return default(TResult);
        }

        /// <summary>
        /// 异步执行方法-有参数有返回值的调用
        /// </summary>
        /// <typeparam name="T">参数对象泛型</typeparam>
        /// <typeparam name="TResult">返回值对象泛型</typeparam>
        /// <param name="func">方法名</param>
        /// <param name="t">参数</param>
        /// <returns>返回Task对象</returns>
        public static async Task<TResult?> RunAsync<T, TResult>(Func<T, TResult> func, T t)
        {
            try
            {
                await Task.Run(() =>
                {
                    return func(t);
                });
            }
            catch { }
            return default(TResult);
        }

        /// <summary>
        /// 异步执行方法-有参数有返回值的调用
        /// </summary>
        /// <typeparam name="T1">参数对象泛型</typeparam>
        /// <typeparam name="T2">参数对象泛型</typeparam>
        /// <typeparam name="TResult">返回值对象泛型</typeparam>
        /// <param name="func">方法名</param>
        /// <param name="t1">参数</param>
        /// <param name="t2">参数</param>
        /// <returns>返回Task对象</returns>
        public static async Task<TResult?> RunAsync<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 t1, T2 t2)
        {
            try
            {
                await Task.Run(() =>
                {
                    return func(t1, t2);
                });
            }
            catch { }
            return default(TResult);
        }

        /// <summary>
        /// 异步执行方法-有参数有返回值的调用
        /// </summary>
        /// <typeparam name="T1">参数对象泛型</typeparam>
        /// <typeparam name="T2">参数对象泛型</typeparam>
        /// <typeparam name="T3">参数对象泛型</typeparam>
        /// <typeparam name="TResult">返回值对象泛型</typeparam>
        /// <param name="func">方法名</param>
        /// <param name="t1">参数</param>
        /// <param name="t2">参数</param>
        /// <param name="t3">参数</param>
        /// <returns>返回Task对象</returns>
        public static async Task<TResult?> RunAsync<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 t1, T2 t2, T3 t3)
        {
            try
            {
                await Task.Run(() =>
                {
                    return func(t1, t2, t3);
                });
            }
            catch { }
            return default(TResult);
        }

        /// <summary>
        /// 异步执行方法-无参数异步、无参数回调
        /// </summary>
        /// <param name="action">方法名</param>
        /// <param name="callback">回调方法名</param>
        public static async void RunCallAsync(Action action, Action callback)
        {
            try
            {
                Task taskFunc()
                {
                    return Task.Run(() =>
                    {
                        action();
                    });
                }
                await taskFunc();
                callback?.Invoke();
            }
            catch { }
        }

        /// <summary>
        /// 有参数异步、无参数回调
        /// </summary>
        /// <typeparam name="T">参数对象泛型</typeparam>
        /// <param name="action">方法名</param>
        /// <param name="t">参数</param>
        /// <param name="callback">回调方法</param>
        public static async void RunCallAsync<T>(Action<T> action, T t, Action callback)
        {
            try
            {
                Task taskFunc()
                {
                    return Task.Run(() =>
                    {
                        action(t);
                    });
                }
                await taskFunc();
                callback?.Invoke();
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-有参数异步、无参数回调
        /// </summary>
        /// <typeparam name="T1">参数对象泛型</typeparam>
        /// <typeparam name="T2">参数对象泛型</typeparam>
        /// <param name="action">方法名</param>
        /// <param name="t1">参数</param>
        /// <param name="t2">参数</param>
        /// <param name="callback">回调方法</param>
        public static async void RunCallAsync<T1, T2>(Action<T1, T2> action, T1 t1, T2 t2, Action callback)
        {
            try
            {
                Task taskFunc()
                {
                    return Task.Run(() =>
                    {
                        action(t1, t2);
                    });
                }
                await taskFunc();
                callback?.Invoke();
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-有参数异步、无参数回调
        /// </summary>
        /// <typeparam name="T1">参数对象泛型</typeparam>
        /// <typeparam name="T2">参数对象泛型</typeparam>
        /// <typeparam name="T3">参数对象泛型</typeparam>
        /// <param name="action">方法名</param>
        /// <param name="t1">参数</param>
        /// <param name="t2">参数</param>
        /// <param name="t3">参数</param>
        /// <param name="callback">回调方法</param>
        public static async void RunCallAsync<T1, T2, T3>(Action<T1, T2, T3> action, T1 t1, T2 t2, T3 t3, Action callback)
        {
            try
            {
                Task taskFunc()
                {
                    return Task.Run(() =>
                    {
                        action(t1, t2, t3);
                    });
                }
                await taskFunc();
                callback?.Invoke();
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-无参数异步、有参数回调
        /// </summary>
        /// <typeparam name="TResult">func方法返回值对象，callback方法参数对象泛型</typeparam>
        /// <param name="func">方法名</param>
        /// <param name="callback">回调方法名</param>
        public static async void RunCallAsync<TResult>(Func<TResult> func, Action<TResult> callback)
        {
            try
            {
                Task<TResult> taskFunc()
                {
                    return Task.Run(() =>
                    {
                        return func();
                    });
                }
                TResult result = await taskFunc();
                callback?.Invoke(result);
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-有参数异步、有参数回调
        /// </summary>
        /// <typeparam name="T">func方法参数对象泛型</typeparam>
        /// <typeparam name="TResult">func方法返回值对象，callback方法参数对象泛型</typeparam>
        /// <param name="func">方法名</param>
        /// <param name="t">参数</param>
        /// <param name="callback">回调方法名</param>
        public static async void RunCallAsync<T, TResult>(Func<T, TResult> func, T t, Action<TResult> callback)
        {
            try
            {
                Task<TResult> taskFunc()
                {
                    return Task.Run(() =>
                    {
                        return func(t);
                    });
                }
                TResult result = await taskFunc();
                callback?.Invoke(result);
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-有参数异步、有参数回调
        /// </summary>
        /// <typeparam name="T1">func方法参数对象泛型</typeparam>
        /// <typeparam name="T2">func方法参数对象泛型</typeparam>
        /// <typeparam name="TResult">func方法返回值对象，callback方法参数对象泛型</typeparam>
        /// <param name="func">方法名</param>
        /// <param name="t1">参数</param>
        /// <param name="t2">参数</param>
        /// <param name="callback">回调方法名</param>
        public static async void RunCallAsync<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 t1, T2 t2, Action<TResult> callback)
        {
            try
            {
                Task<TResult> taskFunc()
                {
                    return Task.Run(() =>
                    {
                        return func(t1, t2);
                    });
                }
                TResult result = await taskFunc();
                callback?.Invoke(result);
            }
            catch { }
        }

        /// <summary>
        /// 异步执行方法-有参数异步、有参数回调
        /// </summary>
        /// <typeparam name="T1">func方法参数对象泛型</typeparam>
        /// <typeparam name="T2">func方法参数对象泛型</typeparam>
        /// <typeparam name="T3">func方法参数对象泛型</typeparam>
        /// <typeparam name="TResult">func方法返回值对象，callback方法参数对象泛型</typeparam>
        /// <param name="func">方法名</param>
        /// <param name="t1">参数</param>
        /// <param name="t2">参数</param>
        /// <param name="t3">参数</param>
        /// <param name="callback">回调方法名</param>
        public static async void RunCallAsync<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 t1, T2 t2, T3 t3, Action<TResult> callback)
        {
            try
            {
                Task<TResult> taskFunc()
                {
                    return Task.Run(() =>
                    {
                        return func(t1, t2, t3);
                    });
                }
                TResult result = await taskFunc();
                callback?.Invoke(result);
            }
            catch { }
        }

    }
}
